package top.z.orm.handle.osql.chain;

import top.z.orm.core.osql.Op;
import top.z.orm.core.osql.chain.Update;

import static top.z.orm.core.osql.SqlKeyWord.*;

public class UpdateImpl extends AbstractToSql implements Update {

    private boolean isStartWhere = true;
    private boolean isAddAnd     = false;
    private boolean isStartTable = true;
    private boolean isStartSet   = true;

    public UpdateImpl() {
        sql.add(UPDATE);
    }

    @Override
    public Update update(String table) {
        if (isStartTable) {
            sql.add(table);
            isStartTable = false;
        } else {
            sql.add(COMMA).add(table);
        }
        return this;
    }

    @Override
    public Update set(String field, String value) {
        if (!isStartSet) {
            sql.add(COMMA);
        }
        if (isStartSet) {
            sql.add(SET);
            isStartSet = false;
        }
        sql.add(field).add(EQUAL).add("'").add(value).add("'");
        return this;
    }

    @Override
    public Update set(String field, Number value) {
        if (!isStartSet) {
            sql.add(COMMA);
        }
        if (isStartSet) {
            sql.add(SET);
            isStartSet = false;
        }
        sql.add(field).add(EQUAL).add(String.valueOf(value));
        return this;
    }

    @Override
    public Update where() {
        sql.add(WHERE);
        isStartWhere = false;
        return this;
    }

    @Override
    public Update where(String expression) {
        if (isStartWhere) {
            sql.add(WHERE);
            sql.add(expression);
            isStartWhere = false;
        } else {
            if (isAddAnd) {
                sql.add(AND);
            }
            sql.add(expression);
            isAddAnd = true;
        }
        return this;
    }

    @Override
    public Update op(String field, Op opType, String value) {
        if (isAddAnd) {
            sql.add(AND);
        }
        sql.add(field).add(opType.getOperator()).add("'").add(value).add("'");
        isAddAnd = true;
        return this;
    }

    @Override
    public Update op(String field, Op opType, Number value) {
        if (isAddAnd) {
            sql.add(AND);
        }
        sql.add(field).add(opType.getOperator()).add(String.valueOf(value));
        isAddAnd = true;
        return this;
    }

    @Override
    public Update op(String field, String value) {
        return op(field, Op.eq, value);
    }

    @Override
    public Update op(String field, Number value) {
        return op(field, Op.eq, value);
    }

    @Override
    public Update and() {
        sql.add(AND);
        isAddAnd = false;
        return this;
    }

    @Override
    public Update or() {
        sql.add(OR);
        isAddAnd = false;
        return this;
    }
}